home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / labyte.zip / LABYTE.DOC < prev    next >
Text File  |  1992-05-08  |  18KB  |  433 lines

  1.                              Memory Manager
  2.                               Version S1.1
  3.  
  4.      One of the most difficult parts of programming in C is handling
  5. memory and its pointers.  At least, that is what I found.  To help me
  6. reduce these problems, I  wrote LAByte.
  7.  
  8.      The functions provided are:
  9.      1.   Handling the allocation of memory blocks, freeing the blocks,
  10.           checking for memory corruption.
  11.      2.   Provide a method of tracing the entrance into each function.
  12.  
  13.      NOTE: There are two separate traces maintained by the module.  The
  14.            first is for the memory functions and the second is for
  15.            function tracing.
  16.  
  17. Memory Processor Functions
  18.   All calls are "traced".  If an error occurs the trace table is written
  19.   to a file named LATrace.LAC.  Each of the function calls use the file
  20.   name and line number.  You may supply your own file name as a
  21.   character pointer or use the __FILE__ symbol, likewise, you may use
  22.   __LINE__ symbol for the line number.  More on the trace later.
  23.  
  24.  
  25.   Allocation of Memory
  26.  
  27.      Memory is allocated from the far heap.  A far character pointer is
  28.      returned pointing to the first usable byte of the block.  The block
  29.      is initialized to NULLs.
  30.  
  31.   prototype:
  32.      char far *mem_getmain(char *File, int Line, char Fun1, char Fun2, int Size);
  33.  
  34.      char *File = A name that will point you to the module doing the
  35.                   getmain.  You may use the __FILE__ symbol.
  36.  
  37.      int Line =   A number representing the place in the module where the
  38.                   getmain was called.  You may use the __LINE__ symbol.
  39.  
  40.      char Fun1 =  These characters can be set to anything that will help
  41.      char Fun2    point you in the right direction.  I use the selection
  42.                   characters from the main menu and its pull down menu.
  43.  
  44.      int Size =   The size of the memory block to be allocated.
  45.      
  46.   example:
  47.  
  48.      int Samp_Fun()
  49.      {
  50.       char far *Cnfg;
  51.  
  52.        Cnfg = mem_getmain(__FILE__, __LINE__, 'M', 'C', sizeof(CONFIG_DATA));
  53.  
  54.      }
  55.  
  56.   Freeing A Memory Block
  57.      When called, freemain will verify the integrity of the block
  58.      passed, abending if it is not valid or freeing the block and
  59.      returning to the calling return.  This function can only be
  60.      used to free memory blocks allocated by the getmain function
  61.      because of the trace chain and block integrity header and
  62.      trailer.
  63.  
  64.   prototype:
  65.      int mem_freemain(char *File, int Line, char far *Pointer);
  66.  
  67.      char *File = A name that will point you to the module doing the
  68.                   getmain.  You may use the __FILE__ symbol.
  69.  
  70.      int Line =   A number representing the place in the module where the
  71.                   getmain was called.  You may use the __LINE__ symbol.
  72.  
  73.      char far *Pointer = The pointer returned from the call to getmain.
  74.      
  75.   example:
  76.  
  77.      int Samp_Fun()
  78.      {
  79.       char far *Cnfg;
  80.  
  81.        mem_freemain(__FILE__, __LINE__, Cnfg);
  82.  
  83.      }
  84.  
  85.  
  86.   Freeing Memory Blocks By A Function
  87.      When called, cleanup will verify the integrity of all blocks
  88.      on the chain where the passed function matches the char passed in
  89.      Fun1 of the getmain, abending if an invalid is encountered or
  90.      freeing the block and returning to the calling return.  The reason
  91.      for using cleanup is to eliminate the build up of unreleased memory
  92.      as a function ends or as a quick and easy way to release all memory
  93.      that was allocated to accomplish the function.
  94.  
  95.   prototype:
  96.      int mem_cleanup(char *File, int Line, char Fun);
  97.  
  98.      char *File = A name that will point you to the module doing the
  99.                   getmain.  You may use the __FILE__ symbol.
  100.  
  101.      int Line =   A number representing the place in the module where the
  102.                   getmain was called.  You may use the __LINE__ symbol.
  103.  
  104.      char Fun =   The character passed in Fun1 of the getmain for the
  105.                   blocks to be released.
  106.      
  107.   example:
  108.  
  109.      int Samp_Fun()
  110.      {
  111.  
  112.        mem_cleanup(__FILE__, __LINE__, 'M');
  113.  
  114.      }
  115.  
  116.  
  117.   Freeing All Memory Blocks
  118.      When called, freeall will verify the integrity of all blocks
  119.      on the chain, abending if invalid or freeing the blocks and
  120.      returning to the calling return.
  121.  
  122.   prototype:
  123.      int mem_freeall(char *File, int Line);
  124.  
  125.      char *File = A name that will point you to the module doing the
  126.                   getmain.  You may use the __FILE__ symbol.
  127.  
  128.      int Line =   A number representing the place in the module where the
  129.                   getmain was called.  You may use the __LINE__ symbol.
  130.      
  131.   example:
  132.  
  133.      int Samp_Fun()
  134.      {
  135.  
  136.        mem_freeall(__FILE__, __LINE__);
  137.  
  138.      }
  139.  
  140.  
  141.   Memory Trace Entry
  142.  
  143.      Internal table
  144.           Memory trace entries are allocated from the near heap as
  145.           memory is allocated and added to the chain.  The first trace
  146.           entry address is saved in the anchor in LAByte.C named
  147.           MemAnchor.
  148.  
  149.           typedef struct {
  150.               int  MemOK;        /* Normally NULL but set to a value
  151.                                     if an error is detected.  see
  152.                                     Error Codes below                */
  153.               char MemMod[15];   /* File Name from getmain           */
  154.               int  MemLine;      /* Line Number from getmain         */
  155.               char MemFun;       /* Fun1 from getmain                */
  156.               char MemUse;       /* Fun2 from getmain                */
  157.               int  MemLen;       /* Length from getmain              */
  158.               void far *MemAddr; /* Address of the memory block      */
  159.               void *MemPrev;     /* Address of the previous memory trace
  160.                                     entry or the memory anchor in the
  161.                                     header                           */
  162.               void *MemNext;     /* Address of the next memory trace
  163.                                     entry or null if this is the last
  164.                                     entry on the chain               */
  165.           } MEMTBL;
  166.  
  167.      LATrace.Lac File Entry (see Cancelling The Program below)
  168.  
  169. M---5D8D:0004---0---main.c---25---M---C---365---5D75:0008---6C60:0004---0000:0000
  170. ^-A     ^-B     ^-C   ^-D    ^-E  ^-F ^-G  ^-H    ^-I          ^-J         ^-K
  171.           A)  Indicator showing this as a memory trace entry
  172.           B)  Address of this trace entry
  173.           C)  Error Code, see Error Codes below
  174.           D)  File Name
  175.           E)  Line Number
  176.           F)  Fun1
  177.           G)  Fun2
  178.           H)  Length of the memory block
  179.           I)  Address of the memory block
  180.           J)  Address of previous memory trace entry
  181.           K)  Address of next memory trace entry
  182.  
  183.      Error codes
  184.           mem_freemain function
  185.             1 - There is no memory on the trace chain
  186.             2 - Can't find find the memory block on the chain
  187.             3 - The backward chain has been corrupted
  188.             4 - The forward chain has been corrupted
  189.             5 - The header of the memory block has been corrupted
  190.             6 - The trailer of the memory block has been corrupted
  191.           mem_cleanup function
  192.            11 - The backward chain has been corrupted
  193.            12 - The header of a memory block has been corrupted
  194.            13 - The trailer of a memory block has been corrupted
  195.           mem_freeall function
  196.            21 - The backward chain has been corrupted
  197.            22 - The header of a memory block has been corrupted
  198.            23 - The trailer of a memory block has been corrupted
  199.           If the trailer of a memory block has been corrupted,
  200.           error codes 6, 13 and 23, probably the definition of the area
  201.           is larger than the memory block allocated.
  202.           If the header is corrupted, error codes 5, 12 and 22,
  203.           either the pointer has been changed, an array was
  204.           improperly indexed or the previous area was overrun.
  205.           For all other error codes, the memory trace chain has
  206.           been corrupted in some fashion.  Since the chain is
  207.           allocated from the near heap, it should not be effected
  208.           by your program.  The problem could be caused If a pointer
  209.           gets incorrectly set, if your program allocates areas from the
  210.           near heap and corrupts it, or a program bug in LAByte.
  211.  
  212.  
  213. Function Tracing Functions
  214.      Function tracing is an optional facility provided to determine the
  215.      logic path through your program.  Entries are placed in the trace
  216.      table by calling function trace_entry.  The trace table is anchored
  217.      to the TraceTbl pointer in LAByte.C.  The table, by default, is
  218.      large enough to hold the last 100 entries.  The size of the table
  219.      can be changed by changing the define TRACEELEMS in the header.
  220.      Because of performance, the trace table is held in memory until the
  221.      program calls cancel_program.  Cancel_program will be called if the
  222.      memory processor functions detect an error or by your program.  The
  223.      trace table can be used during testing if a debugger is not the
  224.      best answer to a particular problem.  Also the trace can be left
  225.      active in the production version of your program and your customer
  226.      can upload the LATrace.Lac file to help you determine what occurred
  227.      if your program should fail.
  228.      I have NOT noticed any measurable performance impact by using this
  229.      trace but some impact may be noticiable if it is called too often.
  230.      But this should only be important in the production version of your
  231.      program.  If you need to create a "lot" of trace entries to
  232.      debug a problem, the size of the trace table should be increased.
  233.  
  234.   Activating/Deactivating The Trace
  235.      The trace logic can be activated or deactivated by the presence or
  236.      absence of a define for LATRACE in LAByte.C.  If present, the trace
  237.      logic will be active.  If LATRACE is absent, the trace table will
  238.      not be allocated and calls to trace_entry will simply issue a return.
  239.  
  240.  
  241.   Placing An Entry In The Trace Table
  242.      I normally place a call to trace_entry as the first function of
  243.      each of my functions and denote it with a type of E.  Additional
  244.      entries can be made to pinpoint problems or provide critical
  245.      information if problems occur.
  246.  
  247.   prototype:
  248.      void trace_entry(char Type, char *File, int Line)
  249.  
  250.      char Type =  A character indicating the type of entry being made.
  251.  
  252.      char *File = A name that will point you to the module doing the
  253.                   getmain.  You may use the __FILE__ symbol.
  254.  
  255.      int Line =   A number representing the place in the module where the
  256.                   getmain was called.  You may use the __LINE__ symbol.
  257.      
  258.   example:
  259.  
  260.      int Samp_Fun()
  261.      {
  262.        trace_entry('E', __FILE__, __LINE__);  /* Trace Entry to Paragraph */
  263.  
  264.      }
  265.  
  266.  
  267.   Cancelling The Program And Dumping The Trace Table To A File
  268.      This function is used to write both the memory trace table and the
  269.      function trace table to LATrace.Lac.  Even if the trace logic is
  270.      disabled, the memory trace is written.  This function does NOT
  271.      return.
  272.      There is a sample of LATrace.Lac provided.
  273.  
  274.   prototype:
  275.      void cancel_prog(int ExitCode)
  276.  
  277.      int ExitCode = The code that is used to exit() the program after
  278.                     the trace table is written.
  279.      
  280.   example:
  281.  
  282.      int Samp_Fun()
  283.      {
  284.  
  285.        cancel_prog(4);
  286.      }
  287.  
  288.  
  289.   Function Trace Entry
  290.  
  291.      Internal table
  292.           Function trace entries are held in the TraceTbl as defined in
  293.           the LAByte.C file.  Room is provided for 100 entries by
  294.           default but can be changed by changing the value of the
  295.           TRACEELEMS define.
  296.  
  297.                #define TRACEELEMS 100 /* Size of trace table */
  298.                typedef struct
  299.                {
  300.                    char Wrap;        /* Indicates if table is wrapping */
  301.                    int TracePtr;     /* Pointer to the current entry   */
  302.                    struct
  303.                    {
  304.                        char Type;    /* Type from trace_entry          */
  305.                        char Mod[15]; /* File from trace_entry          */
  306.                        int  Line;    /* Line from trace_entry          */
  307.                    } TraceElem[TRACEELEMS];
  308.                } TRACETBL;
  309.                TRACETBL *TraceTbl = NULL;
  310.  
  311.      LATrace.Lac File Entry
  312.  
  313. T---E---main.c---21
  314. ^-A ^-B  ^-C     ^-D
  315.           A)  Indicator showing this as a function trace entry
  316.           B)  Type of trace_entry
  317.           C)  File of trace_entry
  318.           D)  Line of trace_entry
  319.  
  320.  
  321. Including In Your Program
  322.      Place LAByte in the directory containing the other modules of your
  323.      program.  Include the module in your .Mak file or project file for
  324.      the IDE.  Change your program to call the routines and recompile
  325.      the program.  The LAByte header need only be included in LAByte.C.
  326.  
  327.  
  328. EXAMPLES OF USE
  329. 1.   Storage overlay
  330.      int stg_overlay()
  331.      {
  332.       char far *BadFld;
  333.           BadFld = mem_getmain(__FILE__, _LINE__, '1', '2', 20);
  334.           memset(BadFld, ' ', 30);
  335.      }
  336.      As a result of the memset, 10 bytes after the area allocated by the
  337.      getmain are set to blanks.  Depending on the use of these bytes the
  338.      program could abort immediately, destroy data or function without
  339.      any indication of the bug.  The worse possible situation to occur
  340.      is the last because the program may start abending after future
  341.      changes are made and it will be almost impossible to relate the
  342.      problem to the actual changes made.  At least with the first two
  343.      cases you are more apt to realize that a problem exists and take
  344.      steps to correct it.
  345.      When a free function is called, the corruption will be detected and
  346.      the memory trace written to LATrace.Lac in the current directory.
  347.      From the memory trace, the bad area can be determined an you will
  348.      know where the area was allocated.  From the function trace, you
  349.      can determine the logic path that lead to the problem.
  350.  
  351. 2.   Program loop
  352.      Finding a loop, which is why, in most cases, the system "locks up",
  353.      can take a significant amount of time depending on the size and
  354.      complexity of the logic.  A good debugger helps.  By including the
  355.      trace_entry as the first function call of each function, to find a
  356.      loop would look like this:
  357.           Start the program executing under the debugger.
  358.           When the program loops, break the code.
  359.           Find the trace table in LAByte.
  360.           Find the current entry.
  361.           Scan backward to find the functions particpating in the loop.
  362.           This will help you determine where to put the breakpoints in
  363.             the debugger.
  364.  
  365.  
  366. LAByte is Shareware
  367.      These routines are supplied on an as-is basis.  We attempt to
  368. insure the accuracy of all our products.  We do warrant that our
  369. software will not cause corruption of the information contained on the
  370. disk containing this product with the exception of that caused by
  371. hardware failures and that caused by a virus.  We gaurantee that the
  372. software is virus free when uploaded to the original BBS but we cannot
  373. prevent its infection beyond that point.  Because this module is
  374. provided as source code and not in executable form,  it is unlikely to
  375. be infected.  To avoid problems with viruses, we recommend that you use
  376. a good virus scanning product on this product and ALL software
  377. downloaded from a BBS.  If you detect such a virus, we would like to
  378. know about it as soon as possible.
  379.  
  380.      The routines are written in Borland C++ from Borland International.
  381. The code is not object-oriented.
  382.  
  383.      You may freely copy and share this program as long as the routines
  384. and documentation are copied in their entirity.
  385.  
  386.      These routines are provided as a shareware product.  You may use it
  387. without registering it for a reasonable time.  The routines may not be
  388. included in any product, except for your own personal use, without
  389. registering it.  If you should decide to register it, we will send you
  390. any corrections that may come to our attention.  In addition, you will
  391. be made aware other products from the Programming Support Division of
  392. Logical Answers Corp as they become available.
  393.  
  394.  
  395.  
  396. Registration Form:
  397.  
  398.      Name: _____________________________________________
  399.  
  400.      Company: __________________________________________
  401.  
  402.      Street: ___________________________________________
  403.  
  404.              ___________________________________________
  405.  
  406.      City: __________________  State: ____  Zip: _______
  407.  
  408.  
  409.      Product: PS01   Serial #: S1A0001
  410.  
  411.      Where did you get your copy of this product?
  412.  
  413.        _________________________________________________
  414.  
  415.  
  416.      Do you want to be added to our mailing list? ______
  417.  
  418.  
  419.                            Registration Fee:       15.00
  420.  
  421.                                Pa. Tax (6%):      ______
  422.  
  423.  
  424.      Send your registration to:
  425.                          Logical Answers Corp.
  426.                          Programming Support Division
  427.                          P. O. Box 33
  428.                          Brownstown, PA 17508
  429.  
  430.                          (717) 627-4181
  431.  
  432.  
  433.